package com.nd.zhanghua;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;

public class App20170929 {
    public static void main(String[] args) {
        List<String> categories = new ArrayList<>();
        List<ServiceNode> nodes = new ArrayList<>();
        List<ServiceNode> nodes1 = new ArrayList<>();
        List<ServiceNode> nodes2 = new ArrayList<>();
        List<ServiceNode> nodes3 = new ArrayList<>();
        List<ServiceNode> nodes4 = new ArrayList<>();
        List<ServiceNode> nodes5 = new ArrayList<>();
        HashMap<String, ServiceLink> linksMap = new HashMap<>();

        categories.add("网关服务");
        categories.add("监控服务");
        categories.add("101教育");
        categories.add("VR教育");
        categories.add("测评");
        categories.add("课程");
        categories.add("个人中心");

        nodes1.add(new ServiceNode("网关-101教育", 0, 0, 0, "网关服务"));
        nodes1.add(new ServiceNode("网关-VR教育", 0, 0, 0, "网关服务"));
        nodes1.add(new ServiceNode("网关-微服务", 0, 0, 0, "网关服务"));

        nodes2.add(new ServiceNode("监控", 0, 0, 0, "监控服务"));

        Random random = new Random();
        //教育
        for (int i = 0; i < 10; i++) {
            nodes3.add(new ServiceNode("101-" + i, 0, 0, 0, "101教育"));
        }
        for (int i = 0; i < 10; i++) {
            nodes4.add(new ServiceNode("VR-" + i, 0, 0, 0, "VR教育"));
        }
        for (int i = 0; i < 30; i++) {
            int r = random.nextInt(3) + 4;
            String category = categories.get(r);
            nodes5.add(new ServiceNode(category + i, 0, 0, 0, category));
        }
        nodes1.forEach(n -> {
            addLink(linksMap, random, n, nodes2.get(0));
        });
        nodes3.forEach(n -> {
            addLink(linksMap, random, n, nodes2.get(0));
            addLink(linksMap, random, n, nodes1.get(0));
        });
        nodes4.forEach(n -> {
            addLink(linksMap, random, n, nodes2.get(0));
            addLink(linksMap, random, n, nodes1.get(1));
        });
        nodes5.forEach(n -> {
            addLink(linksMap, random, n, nodes2.get(0));
            addLink(linksMap, random, n, nodes1.get(2));
        });
        ServiceLink link = new ServiceLink();
        link.source = "网关-VR教育";
        link.target = "网关-微服务";
        link.value = 999999;
        link.errorCall = 88888;
        linksMap.put(link.source + link.target, link);

        link = new ServiceLink();
        link.source = "网关-101教育";
        link.target = "网关-微服务";
        link.value = 800000;
        link.errorCall = 7777;
        linksMap.put(link.source + link.target, link);

        link = new ServiceLink();
        link.source = "VR-1";
        link.target = "101-1";
        link.dependentType = -1;
        link.value = 800000;
        link.errorCall = 7777;
        linksMap.put(link.source + link.target, link);


        link = new ServiceLink();
        link.source = "VR-1";
        link.target = "101-1";
        link.dependentType = -1;
        link.value = 800000;
        link.errorCall = 7777;
        linksMap.put(link.source + link.target, link);

        link = new ServiceLink();
        link.source = "VR-1";
        link.target = "101-1";
        link.dependentType = -1;
        link.value = 800000;
        link.errorCall = 7777;
        linksMap.put(link.source + link.target, link);


        link = new ServiceLink();
        link.source = nodes4.get(0).name;
        link.target = nodes5.get(0).name;
        link.dependentType = 0;
        link.value = 500000;
        link.errorCall = 7777;
        linksMap.put(link.source + link.target, link);



        /*for (int i = 0; i < nodes.size() * (nodes.size() - 1); i++) {
            ServiceNode source = nodes.get(Math.abs(random.nextInt()) % nodes.size());
            ServiceNode target = nodes.get(Math.abs(random.nextInt()) % nodes.size());
            if (source.name.equals(target.name)) {
                continue;
            }
            if (source.category.equals(target.category)) {
                continue;
            }
            if (source.category.equals("网关服务") || source.category.equals("监控服务")) {
                continue;
            }
            if ("101教育|VR教育".contains(source.category)) {
                if ("101教育|VR教育".equals(target.category)) {
                    continue;
                }
            }
            if ("测评|课程|个人中心".contains(source.category)) {
                if ("测评|课程|个人中心".equals(target.category)) {
                    continue;
                }
            }
            if ("个人中心".contains(target.category)) {
                if (!"监控服务".equals(source.category)) {
                    continue;
                }
            }
            String mapKey = source.name + target.name;
            if (!linksMap.containsKey(mapKey)) {
                ServiceLink link = new ServiceLink();
                link.source = source.name;
                link.target = target.name;
                link.value = Math.abs(random.nextInt(1000000));
                link.errorCall = Math.abs(random.nextInt(1000000));
                target.value = target.value + 1;
                linksMap.put(mapKey, link);
            }
        }*/
        nodes.addAll(nodes1);
        nodes.addAll(nodes2);
        nodes.addAll(nodes3);
        nodes.addAll(nodes4);
        nodes.addAll(nodes5);
        nodes.add(new ServiceNode("来刷存在感的", 100, 100, 100, "打酱油"));
        Data data = new Data(nodes, linksMap.values(), categories);
        Gson gson = new Gson();
        String str = gson.toJson(data);
        try {
            FileUtils.write(new File("E:\\Source\\Html\\echartslearn\\serviceInfo.txt"), str, "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        //gexf
        StringBuilder sb = new StringBuilder(512);
        sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                "<gexf xmlns=\"http://www.gexf.net/1.3\" version=\"1.3\" xmlns:viz=\"http://www.gexf.net/1.3/viz\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.gexf.net/1.3 http://www.gexf.net/1.3/gexf.xsd\">\n" +
                "\t<meta lastmodifieddate=\"2017-09-30\">\n" +
                "\t\t<creator>Gephi 0.9</creator>\n" +
                "\t\t<description></description>\n" +
                "\t</meta>\n" +
                "\t<graph defaultedgetype=\"directed\" mode=\"static\">\n<nodes>");
        nodes.forEach((n) -> {
            sb.append("\t\t\t<node id=\"" + n.name + "\"/>\n");
        });
        sb.append("</nodes>\n");

        sb.append("<edges>\n");
        int index = 0;
        for (ServiceLink l : data.links) {
            sb.append(String.format("\t\t\t<edge source=\"%s\" target=\"%s\" weight=\"%s\"/>\n",
                    l.source, l.target, l.value == 0 ? 1 : l.value));
        }
        sb.append("\t\t</edges>\n" +
                "\t</graph>\n" +
                "</gexf>");
        try {
            FileUtils.write(new File("E:\\Source\\graph.gexf"), sb.toString(), "utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void addLink(HashMap<String, ServiceLink> linksMap, Random random, ServiceNode source, ServiceNode target) {
        String mapKey = source.name + target.name;
        if (!linksMap.containsKey(mapKey)) {
            ServiceLink link = new ServiceLink();
            link.source = source.name;
            link.target = target.name;
            if (source.category.equals("VR教育") && target.category.equals("监控服务")) {
                link.dependentType = 1;
            } else {
                link.value = Math.abs(random.nextInt(100000));
                link.errorCall = Math.abs(random.nextInt(100000));
                link.avgTime = Math.abs(random.nextInt(100000));
            }
            target.value = target.value + 1;
            linksMap.put(mapKey, link);
        }
    }

    @AllArgsConstructor
    @NoArgsConstructor
    private static class Data {
        public Collection<ServiceNode> nodes;
        public Collection<ServiceLink> links;
        public Collection<String> categories;
    }

    @AllArgsConstructor
    @NoArgsConstructor
    private static class ServiceNode {
        public String name;
        public int x;
        public int y;
        public int value;
        public String category;
    }

    @AllArgsConstructor
    @NoArgsConstructor
    private static class ServiceLink {
        public String source;
        public String target;
        public int dependentType = 1;
        public int value;
        public int errorCall;
        public int avgTime;
    }
}
